package com.changgou.seckill.timer;


import com.changgou.seckill.dao.SeckillGoodsMapper;
import com.changgou.seckill.pojo.SeckillGoods;
import entity.DateUtil;
import entity.SystemConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.Set;

@Component
public class SeckillGoodsPushTask {



    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * cron表达式
     *
     */
    @Scheduled(cron = "0/5 * * * * ? ")   //从0秒开始,每隔五秒执行一次
    public void pusGoodsTask(){

        System.out.println("日期: "+ new Date());
        //获取时间段集合
        List<Date> dateMenus = DateUtil.getDateMenus();
        //循环时间段
        for (Date startTime : dateMenus) {
            // namespace = SeckillGoods_20195712
            String extName = DateUtil.data2str(startTime,DateUtil.PATTERN_YYYYMMDDHH);

            //根据时间段数据查询对应的秒杀商品数据
            Example example = new Example(SeckillGoods.class);
            Example.Criteria criteria = example.createCriteria();
            // 1)商品必须审核通过  status=1
            criteria.andEqualTo("status","1");
            // 2)库存>0
            criteria.andGreaterThan("stockCount",0);
            // 3)开始时间<=活动开始时间
            criteria.andGreaterThanOrEqualTo("startTime",startTime);
            // 4)活动结束时间<开始时间+2小时
            criteria.andLessThan("endTime", DateUtil.addDateHour(startTime,2));

            // 5)排除之前已经加载到Redis缓存中的商品数据
            // key :就是时间段:2019121010    fidl值: 商品id     value:商品信息

            Set keys = redisTemplate.boundHashOps("SeckillGoods_" + extName).keys();  //得到当前时间的商品id的所有
            if(keys!=null && keys.size()>0){  //当不为null并且大小大于0的时候就排除
                criteria.andNotIn("id",keys);   //只要redis中存在的id内容就不添加,防止重复
            }

            //查询数据
            List<SeckillGoods> seckillGoods = seckillGoodsMapper.selectByExample(example);

            //将秒杀商品数据存入到Redis缓存
            for (SeckillGoods seckillGood : seckillGoods) {
                //存入数据
                redisTemplate.boundHashOps("SeckillGoods_"+extName).put(seckillGood.getId(),seckillGood);

                //设置有效时间:当前时间往后两个小时: 开始时间+2小时
                redisTemplate.expireAt("SeckillGoods_"+extName,DateUtil.addDateHour(startTime, 2));


                //将商品压入队列中防止超卖现象:一开始商品就让他压入,这样取出就可以有顺序
                //pushGoodsResisList(seckillGood);
            }
        }
    }


    //用来压入队列,防止超卖
    private  void pushGoodsResisList(SeckillGoods seckillGood){
        for (Integer i = 0; i < seckillGood.getStockCount(); i++) {
            redisTemplate.boundListOps(SystemConstants.SEC_KILL_CHAOMAI_LIST_KEY_PREFIX+seckillGood.getId()).leftPush(seckillGood.getId());
        }
    }
}
